﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Intel.Server.WCFLibrary
{

    public class SessionManager
    {
        public SessionManager(IValidator V)
        {
            v = V;
        }
        public  Session this[string SessionId]
        {
            get
            {
                lock (this)
                {
                    if(!Sessions.ContainsKey(SessionId))
                        throw new SystemException("Invalid Session");
                    return  Sessions[SessionId];
                }
            }
            
        }
        public  Session RequestSession(string UserName, string PassWord)
        {
            lock (this)
            {
                if (NameKey.ContainsKey(UserName))
                {
                    var session = NameKey[UserName];
                    session.UpdataDeadTime(Duration);
                    return session;
                }

            }
            int id = v.Validate(UserName, PassWord);
            if (id <= 0)
                throw new SystemException("Invalid username and password");
            lock (this)
            {
                if (Sessions.Count < maxSession)
                {
                    Session NewSession;
                    if (SessionPool.Count > 0)
                    {
                        NewSession = SessionPool.Pop();

                    }
                    else
                    {
                        NewSession = new Session();
                    }
                    string SessionId;
                    do 
                    {
                       SessionId = GenerateSessionId(SessionIdLength);
                    } while (Sessions.ContainsKey(SessionId));
                    
                    NewSession.Set(id,SessionId, UserName, Session.UserType.RegUser, Duration);
                    Sessions.Add(SessionId, NewSession);
                    NameKey.Add(UserName, NewSession);
                    return NewSession;
                }
                else
                    throw new SystemException("Max Session Reached");
            }
        }
        public bool Validate(string Username, string Password)
        {
            return v.Validate(Username, Password) > 0;
        }

        
        private TimeSpan Duration = new TimeSpan(0, 2, 0);
        private int maxSession = 500;
        private int SessionIdLength = 24;


        private Dictionary<string, Session> Sessions = new Dictionary<string, Session>();
        private Dictionary<string, Session> NameKey = new Dictionary<string, Session>();
        private Stack<Session> SessionPool = new Stack<Session>();
        private IValidator v;
        private string GenerateSessionId(int codeCount)
        {
            string str = string.Empty;
            long num2 = DateTime.Now.Ticks;
            Random random = new Random(((int)(((ulong)num2) & 0xffffffffL)) | ((int)(num2 >> 5)));
            for (int i = 0; i < codeCount; i++)
            {
                char ch;
                int num = random.Next();
                if ((num % 2) == 0)
                {
                    ch = (char)(0x30 + ((ushort)(num % 10)));
                }
                else
                {
                    ch = (char)(0x41 + ((ushort)(num % 0x1a)));
                }
                str = str + ch.ToString();
            }
            return str;
        }
    }
}
